use sqlx::PgPool;

use crate::errors::MyError;
// use crate::models::course::Course;
use crate::handlers::course::models::course::Course;
use crate::models::course::{CreateCourse,UpdateCourse};

pub async fn get_course_for_teacher_id(pool: &PgPool, teacher_id: i32) -> Result<Vec<Course>,MyError>{
    let rows = sqlx::query_as::<_,Course>("select * from course where teacher_id = $1")
        .bind(teacher_id)
        .fetch_all(pool)
        .await?;
    match rows.len() {
        0 => Err(MyError::NotFound("Courses not found for teacher".into())),
        _ => Ok(rows)
    }
}

pub async fn get_course_details_db(pool: &PgPool,teacher_id: i32,course_id: i32) -> Result<Course,MyError>{
    let rows = sqlx::query_as::<_,Course>(
        r#"select * from course where teacher_id = $1 and id = $2"#
    ).bind(teacher_id).bind(course_id)
        .fetch_optional(pool)
        .await?;
    if let Some(row) = rows{
        Ok(row)
    }
    else {
        Err(MyError::NotFound("Course is not found".into()))
    }
}

pub async fn post_new_course_db(pool: &PgPool,new_course: CreateCourse) -> Result<Course,MyError>{
   let rows = sqlx::query_as::<_,Course>(
       r#"Insert into course (teacher_id,name) values ($1,$2)
       RETURNING id teacher_id,name,time"#,
   ).bind(new_course.teacher_id).bind(new_course.name).fetch_one(pool).await?;
    Ok(rows)
}

pub async fn delete_course_db(pool: &PgPool,teacher_id: i32,id: i32) -> Result<String, MyError>{
    let course_row = sqlx::query!(
        "DELETE from course where teacher_id = $1 and id = $2",
        teacher_id,
        id
    ).execute(pool).await?;
    Ok(format!("Delete {:?} from course",course_row))
}

pub async fn update_course_details_db(pool: &PgPool,teacher_id: i32,course_id: i32,update_course: UpdateCourse) -> Result<Course,MyError>{
    let rows = sqlx::query_as::<_,Course>(
        "Select * from course where teacher_id = $1 and id = $2",
    ).bind(teacher_id)
        .bind(course_id)
        .fetch_one(pool)
        .await
        .map_err(|_err| MyError::NotFound("course details not found".to_string()))?;
    let name = if let Some(name) = update_course.name{
        name
    }else {
        rows. name
    };
    let course_row = sqlx::query_as::<_,Course>(
        "update course set name = $1 where id = $2",
    ).bind(name).bind(course_id).fetch_one(pool).await;
    if let Ok(course) = course_row{
        Ok(course)
    }
    else {
        Err(MyError::NotFound("course details not found".to_string()))
    }

}